package com.github.itdachen.auth.oauth.rbac.auth;

import com.github.itdachen.auth.oauth.rbac.IRbacPermissionHandler;
import com.github.itdachen.auth.oauth.rbac.storage.IAppPermissionStorageHandler;
import com.github.itdachen.auth.oauth.rbac.storage.IUserPermissionStorageHandler;
import com.github.itdachen.framework.context.permission.CheckPermissionInfo;
import com.github.itdachen.framework.context.permission.PermissionInfo;
import com.github.itdachen.framework.context.userdetails.UserInfoDetails;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 权限校验的实现 data source
 *
 * @author 王大宸
 * @date 2025-02-18 15:00
 */
@Service
public class VerifyRbacPermissionHandler implements IRbacPermissionHandler {

    private final IAppPermissionStorageHandler appPermissionHandler;
    private final IUserPermissionStorageHandler userPermissionHandler;

    public VerifyRbacPermissionHandler(IAppPermissionStorageHandler appPermissionHandler,
                                       IUserPermissionStorageHandler userPermissionHandler) {
        this.appPermissionHandler = appPermissionHandler;
        this.userPermissionHandler = userPermissionHandler;
    }

    @Override
    public CheckPermissionInfo handler(UserInfoDetails userInfoDetails,
                                       String requestUri,
                                       String requestMethod) {
        CheckPermissionInfo checkPermissionInfo = new CheckPermissionInfo();
        List<PermissionInfo> allPermission = this.appPermissionHandler.findAppPermissions();

        if (allPermission.isEmpty()) {
            checkPermissionInfo.setIsAuth(true);
            return checkPermissionInfo;
        }

        // 判断当前访问资源是否有权限控制
        List<PermissionInfo> matchPermission = allPermission.parallelStream()
                .filter(permissionInfo -> {
                    String uri = permissionInfo.getUri();
                    if (uri.indexOf("{") > 0) {
                        uri = uri.replaceAll("\\{\\*\\}", "[a-zA-Z\\\\d]+");
                    } else {
                        uri = uri.replaceAll("\\*", "[a-zA-Z\\\\d]+");
                    }
                    String regEx = "^" + uri + "$";
                    return Pattern.compile(regEx).matcher(requestUri).find()
                            && requestMethod.equals(permissionInfo.getMethod());
                }).collect(Collectors.toList());

        // 说明当前访问资源不做权限控制
        if (matchPermission.isEmpty()) {
            checkPermissionInfo.setIsAuth(true);
            return checkPermissionInfo;
        }


        // 判断当前用户是否拥有该访问资源的权限
        List<PermissionInfo> permissions = userPermissionHandler.findUserPermissions(userInfoDetails);
        if (null == permissions) {
            checkPermissionInfo.setIsAuth(false);
            checkPermissionInfo.setPermissionInfo(matchPermission.get(0));
            return checkPermissionInfo;
        }
        PermissionInfo current = null;
        boolean anyMatch;
        for (PermissionInfo info : permissions) {
            anyMatch = matchPermission
                    .parallelStream()
                    .anyMatch(permissionInfo -> permissionInfo.getPermission().equals(info.getPermission()));
            if (anyMatch) {
                current = info;
                break;
            }
        }

        // 当前用户不拥有该权限
        if (null == current) {
            checkPermissionInfo.setIsAuth(false);
            return checkPermissionInfo;
        }
        // 当前用户拥有该资源的访问权限
        checkPermissionInfo.setIsAuth(true);
        checkPermissionInfo.setPermissionInfo(current);
        return checkPermissionInfo;
    }

}
